package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.CarPackageAuditMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.business.service.ProcessService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 审核列表Service业务层处理
 *
 * @author x1ao
 * @date 2021-07-21
 */
@Service
public class CarPackageAuditServiceImpl implements ICarPackageAuditService {
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private ProcessService processService;
    @Autowired
    private IServiceItemService serviceItemService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;

    /**
     * 查询审核列表
     *
     * @param id 审核列表ID
     * @return 审核列表
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id) {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询审核列表列表
     *
     * @param carPackageAudit 审核列表
     * @return 审核列表
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit) {
        List<CarPackageAudit> audits = carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
        Task task = null;
        for (CarPackageAudit audit : audits) {
            audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));
            task = processService.selectTaskByInstanceId(audit.getInstanceId());
            if (task != null) {
                audit.setTaskId(task.getId());
                audit.setTaskName(task.getName());
            } else {
                audit.setTaskName("任务已结束");
            }
        }
        return audits;
    }

    /**
     * 新增审核列表
     *
     * @param carPackageAudit 审核列表
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit) {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改审核列表
     *
     * @param carPackageAudit 审核列表
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit) {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 删除审核列表对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(String ids) {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除审核列表信息
     *
     * @param id 审核列表ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id) {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }


    @Override
    public void cancelApply(String instanceId) {
        ProcessInstance processInstance = processService.getProcessInstanceByInstanceId(instanceId);
        String businessKey = processInstance.getBusinessKey();
        CarPackageAudit audit = carPackageAuditMapper.getCarPackageAudit(businessKey);
        audit.setAuditors("");
        audit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAuditMapper.updateCarPackageAudit(audit);
        ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class);
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        serviceItemService.updateServiceItemNoCondition(serviceItem);
        processService.deleteProcessInstance(instanceId, "用户撤销");
    }

    @Override
    public List<CarPackageAudit> selectTodoList(CarPackageAudit carPackageAudit) {
        //查询当前登录用户关于汽车审核流程任务的全部待办数量
        Long count = processService.selectTodoTaskListCount(CarPackageAudit.DEFINITION_KEY, ShiroUtils.getUserId().toString());
        if (count > 0) {
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageSize = pageDomain.getPageSize();
            Integer pageNum = pageDomain.getPageNum();
            //查询当前登录用户关于汽车审核流程任务的全部待办
            List<Task> resultList = processService.selectTodoTaskList(CarPackageAudit.DEFINITION_KEY,
                    ShiroUtils.getUserId().toString(),
                    (pageNum - 1) * pageSize,
                    pageSize);
            List<CarPackageAudit> auditList = new ArrayList<>();
            for (Task task : resultList) {
                //遍历待办任务,查寻对应的CarPackAgeAudit
                ProcessInstance processInstance = processService.getProcessInstanceByInstanceId(task.getProcessInstanceId());
                String businessKey = processInstance.getBusinessKey();
                CarPackageAudit audit = carPackageAuditMapper.getCarPackageAudit(businessKey);
                audit.setTaskId(task.getId());
                audit.setTaskName(task.getName());
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));
                auditList.add(audit);
            }
            Page<CarPackageAudit> page = new Page<>();
            page.addAll(auditList);
            page.setPageNum(pageNum);
            page.setTotal(count);
            page.setPageSize(pageSize);
            return auditList;
        } else {
            return Collections.EMPTY_LIST;

            //启动报错:
            //Caused by: org.springframework.security.core.userdetails.UsernameNotFoundException: 1
            //原因是因为Activiti在代码中强耦合了SpringScurity,在使用taskService.taskCandidateUser(candidateUser)
            //会调用SpringScurity中的UserDetailsService类型的bean中的loadUserByUsername方法.然后是找不到的,所以报错了.
            //我们需要调整的是,写一个类实现UserDetailsService然后重写loadUserByUsername方法.
        }
    }

    @Override
    @Transactional
    public void complate(String taskId, Boolean auditStatus, String comment) {
        String commentStr = auditStatus ? "[同意]" : "[拒绝]";
        if (StringUtils.isNotEmpty(comment)) {
            commentStr += comment;
            Task task = processService.getTaskByTaskId(taskId);
            ProcessInstance instance = processService.getProcessInstanceByInstanceId(task.getId());
            //添加批注,设置流程变量,认领任务,完成任务
            processService.claimAndComplateTask(task, ShiroUtils.getUserId().toString(), auditStatus, commentStr);
            //查询下一个任务
            Task nextTask = processService.selectTaskByInstanceId(task.getProcessInstanceId());
            CarPackageAudit audit = carPackageAuditMapper.getCarPackageAudit(instance.getBusinessKey());
            if (nextTask != null) {
                List<String> auditors = new ArrayList<>();
                if (auditStatus){
                    String taskDefinitionKey = nextTask.getTaskDefinitionKey();
                    List<SysUser> auditorList = definitionNodeService.queryAuditorsBytaskDefinitionKey(taskDefinitionKey);
                    for (SysUser auditor : auditorList) {
                        processService.addCandidateUser(nextTask,auditor.getUserId());
                        auditors.add(auditor.getUserName());
                    }
                }else {
                    String userId = audit.getCreateBy();
                    auditors.add(audit.getCreateByName());
                    processService.addCandidateUser(nextTask,Long.parseLong(userId));
                    audit.setStatus(CarPackageAudit.STATUS_REJECT);
                }
                audit.setAuditors(JSON.toJSONString(auditors));
                carPackageAuditMapper.updateCarPackageAudit(audit);
            }else {
                //任务结束
                audit.setAuditors("");
                audit.setStatus(CarPackageAudit.STATUS_PASS);
                carPackageAuditMapper.updateCarPackageAudit(audit);
                ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class);
                serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
                serviceItemService.updateServiceItem(serviceItem);
            }
        }
    }
}
